import { eventBus, timeline, logger } from '@/instance'
import { actionsMap } from '@/constants/actions'
import { EventComposition } from '@/types'
import { ComputedRef, Ref } from 'vue'
import { Track } from '@/core/track'
import { removeClip, splitClip } from '@/console/storyboard'
import { Clip } from '@/core/clip'
import { useHistory } from '../history'

export function useActions(
  currentTime: Ref<number>,
  storyboard: ComputedRef<Track>
): EventComposition {
  logger.log('composables/actions', 'useActions')

  const { undo, redo } = useHistory()

  const toStartAction = () => {
    timeline.currentTime = 0
    logger.log('composables/actions', 'toStartAction')
  }
  const playAction = () => {
    timeline.play()
    logger.log('composables/actions', 'playAction')
  }
  const pauseAction = () => {
    timeline.pause()
    logger.log('composables/actions', 'pauseAction')
  }
  const toEndAction = () => {
    timeline.currentTime = timeline.duration
    logger.log('composables/actions', 'toEndAction')
  }
  const playOrPauseAction = () => {
    timeline.paused ? timeline.play() : timeline.pause()
    logger.log('composables/actions', 'playOrPauseAction')
  }
  const prevFrameAction = () => {
    timeline.currentTime -= 0.03
    logger.log('composables/actions', 'prevFrameAction')
  }
  const nextFrameAction = () => {
    timeline.currentTime += 0.03
    logger.log('composables/actions', 'nextFrameAction')
  }

  const editClipAction = ({ clip, track }: { clip: Clip; track: Track }) => {
    logger.log('composables/actions', 'editClipAction', clip)
  }
  const deleteClipAction = ({ clip, track }: { clip: Clip; track: Track }) => {
    removeClip(track, clip)
    logger.log('composables/actions', 'deleteClipAction', clip)
  }
  const splitClipAction = () => {
    splitClip(storyboard.value, currentTime.value)
    logger.log('composables/actions', 'splitClipAction', currentTime)
  }
  const undoAction = () => {
    undo()
    logger.log('composables/actions', 'undoAction', currentTime)
  }
  const redoAction = () => {
    redo()
    logger.log('composables/actions', 'redoAction', currentTime)
  }

  const bind = () => {
    eventBus.on(actionsMap.TO_START, toStartAction)
    eventBus.on(actionsMap.PLAY, playAction)
    eventBus.on(actionsMap.PAUSE, pauseAction)
    eventBus.on(actionsMap.TO_END, toEndAction)
    eventBus.on(actionsMap.PLAY_OR_PAUSE, playOrPauseAction)
    eventBus.on(actionsMap.PREV_FRAME, prevFrameAction)
    eventBus.on(actionsMap.NEXT_FRAME, nextFrameAction)
    eventBus.on(actionsMap.EDIT_CLIP, editClipAction)
    eventBus.on(actionsMap.DELETE_CLIP, deleteClipAction)
    eventBus.on(actionsMap.SPLIT_CLIP, splitClipAction)
    eventBus.on(actionsMap.UNDO, undoAction)
    eventBus.on(actionsMap.REDO, redoAction)

    logger.log('composables/actions', 'bind')
  }
  const unbind = () => {
    eventBus.off(actionsMap.TO_START, toStartAction)
    eventBus.off(actionsMap.PLAY, playAction)
    eventBus.off(actionsMap.PAUSE, pauseAction)
    eventBus.off(actionsMap.TO_END, toEndAction)
    eventBus.off(actionsMap.PLAY_OR_PAUSE, playOrPauseAction)
    eventBus.off(actionsMap.PREV_FRAME, prevFrameAction)
    eventBus.off(actionsMap.NEXT_FRAME, nextFrameAction)
    eventBus.off(actionsMap.EDIT_CLIP, editClipAction)
    eventBus.off(actionsMap.DELETE_CLIP, deleteClipAction)
    eventBus.off(actionsMap.SPLIT_CLIP, splitClipAction)
    eventBus.on(actionsMap.UNDO, undoAction)
    eventBus.on(actionsMap.REDO, redoAction)
    logger.log('composables/actions', 'unbind')
  }

  return {
    bind,
    unbind,
  }
}
